﻿/*
    IniHelper by notemper2x

    Copyright (C) 2008, TurboZV, turbozv@gmail.com, http://www.turbozv.com/

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.


    *KEEP THIS HEADER INFORMATION*
*/

/*
 * 与标准INI的区别: 
 *     允许在同一个段中多次出现同一个键
 *     多个相同键的值使用 | 分隔保存在同一个键值中
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Specialized;

namespace Helper
{
    public class IniField
    {
        private Dictionary<string, string> m_NameValues;
        public IniField()
        {
            m_NameValues = new Dictionary<string, string>();
        }

        public string this[string key]
        {
            get
            {
                string value;
                if (!m_NameValues.TryGetValue(key.ToLower(), out value))
                {
                    value = String.Empty;
                }

                return value;
            }

            set
            {
                m_NameValues[key.ToLower()] = value;
            }
        }
    }

    /// <summary>
    /// 配置文件容器
    /// </summary>
    public class IniConfig
    {
        private Dictionary<string, IniField> m_fields;

        public IniConfig()
        {
            m_fields = new Dictionary<string, IniField>();
        }

        public IniField GetField(string fieldname)
        {
            return GetField(fieldname, false);
        }

        public IniField GetField(string fieldname, bool force)
        {
            IniField field;
            if (!m_fields.TryGetValue(fieldname.ToLower(), out field))
            {
                if (force)
                {
                    field = new IniField();
                    m_fields[fieldname] = field;
                }
                else
                {
                    field = null;
                }
            }
            return field;
        }

        public IniField this[string fieldname]
        {
            get
            {
                return this.GetField(fieldname);
            }
        }
    }

    public static class IniHelper
    {
        public static IniConfig ReadConfig(string filename)
        {
            IniConfig config = new IniConfig();


            StreamReader reader = File.OpenText(filename);
            try
            {
                IniField lastField = null;

                string lastFieldName = String.Empty;

                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine();

                    // 删除行首空格
                    line.TrimStart();

                    if (line.StartsWith("#"))
                    {
                        continue;
                    }

                    // 删除行尾注释
                    line = Regex.Replace(line, "#.*$", "");

                    // 删除行尾空格
                    line = line.TrimEnd();


                    Match match;

                    // 判断是否是 [fieldname] 段的分隔
                    match = Regex.Match(line, @"^\[([^\]]+)] *$");
                    if (match.Success)
                    {
                        string curFieldName = match.Result("$1");
                        if (String.Compare(curFieldName, lastFieldName, true) != 0)
                        {
                            lastFieldName = curFieldName;
                            lastField = null; // 清空当前 field 以便后面获得新的
                        }
                    }

                    // 取得 key = value 的值
                    match = Regex.Match(line, @"^([^= ]+) *= *(.*?)$");

                    if (!match.Success)
                    {
                        continue;
                    }

                    if (lastField == null)
                    {
                        lastField = config.GetField(lastFieldName, true);
                    }

                    string key = match.Result("$1"); // 当前行的 key
                    string value = match.Result("$2"); // 当前行的 value


                    if (String.IsNullOrEmpty(lastField[key]))
                    {
                        lastField[key] = value;
                    }
                    else
                    {
                        lastField[key] = String.Format("{0}|{1}", lastField[key], value);
                    }
                }
            }
            finally
            {
                reader.Close();
            }

            return config;

        }
    }
}